home *** CD-ROM | disk | FTP | other *** search
- Path: cleveland.Freenet.Edu!bf461
- From: bf461@cleveland.Freenet.Edu (Bryan Murphy)
- Newsgroups: comp.lang.c++
- Subject: C++ OO question (long)
- Date: 28 Feb 1996 00:51:38 GMT
- Organization: Case Western Reserve University, Cleveland, OH (USA)
- Message-ID: <4h08uq$mve@madeline.INS.CWRU.Edu>
- Reply-To: bf461@cleveland.Freenet.Edu (Bryan Murphy)
- NNTP-Posting-Host: owl.ins.cwru.edu
-
-
-
- /*
- Warning: This is a long one.
-
- Ok, I'm fairly new to the C++ programming paradigm. While I've
- quite a bit of experience with the C++ syntax, I've only just
- begun to understand the concepts that really go into an OOP
- program.
-
- Anyways, I have to write a program for a class, all it needs to
- do is multiply two matrices together, but I decided to brush up
- on my C++ and to forgoe using ada or pascal to just throw some-
- thing together.
-
- Bellow is the program I wrote. It implements a class called
- Matrix, which allocates memory on the heap for the storage of
- a matrix of XxY dimensions. It also implements a copy constructor
- for assignment, and a couple of different mathematical operations
- to be performed on the matrix.
-
- I've got one big problem, and one little one, even though this
- does compile and run fine the way it is (I'm compiling this as
- a Visual C++ 4.0 Console Application).
-
- The first problem involves this very peculiar inconsistency that
- I can't explain, for instance, this works:
-
- Matrix M3 = Matrix1 * Matrix2;
-
- whereas defining Matrix M3 ahead of time
-
- M3 = Matrix1 * Matrix2;
-
- crashes out on me giving me an error. I can't really tell why.
- It's a memory allocation assertion error. I can't figure out
- why I can't do the second method. I was thinking about this,
- and I have another question related to this. When I define
- the Matrix M3 and assign it right away, is the Default Blank
- Constructor called, THEN the Copy Constructor? Or just the
- copy constructor? Also, say the copy Constructor was called.
- When the new data is copied over, is the Destructor called
- before the copy constructor is used to copy the new data over?
- I think these questions could definately shed some light as to
- the inconsistency noted above.
-
- Also, my second problem is pretty simple. It relates to using
- variable arguments. Is there anything peculiar or different
- about Visual C++'s variable arguments? I was trying to initialize
- the Matrices by using variable arguments, rather than passing
- a pointer to an array of Integers, but I could not get the
- constructor to get the proper numbers. I was basing the code
- EXACTLY like what was in my C++ for Pascal Programmers book,
- nearly statement by statement, but it didn't work. Visual C++
- accepted the syntax, and everything looked ok, but I was just
- not getting the right values.
-
- Here is the CPP file. It's one file and can be copied. I even
- commented out this text so you can just save the message to
- a file and copy it directly if you would like to take a look at
- it.
-
- Any help would be GREATLY appreciated!
- */
-
- /******************************************************************
-
- Author: Bryan Murphy
- Class: CPS 341
- Teacher: Y. Pan
- Due Date: Monday 3/4/96
-
- This program implements a Matrix class and the appropriate
- Multiplication and Division functions for that class. The
- program then demonstrates the use of this class.
-
- ******************************************************************/
- #include "iostream.h"
- #include "stdarg.h"
- #include "stdlib.h"
-
- class Matrix {
- public:
- Matrix(); // Constructor
- Matrix(int,int,int const *); // Constructor
- ~Matrix(); // Destructor
-
- Matrix(const Matrix &); // Copy Constructor
-
- int GetData(int,int); // Get Number from Matrix
- void SetData(int,int,int); // Set a Value in the Matrix
- void Display(void); // Display Contents of Matrix
-
- int Xdim() { return xdim+1; } // In case the size needs
- int Ydim() { return ydim+1; } // to be checked.
-
- // The following are the operations that can be
- // performed on a matrix.
- friend Matrix operator * (Matrix, Matrix); // Matrix *
- friend Matrix operator * (Matrix, int); // Scalar *
- friend Matrix operator + (Matrix, Matrix); // Matrix +
- friend Matrix operator - (Matrix, Matrix); // Matrix -
-
- private:
-
- int xdim; // X size of Matrix
- int ydim; // Y size of Matrix
-
- int *MatrixData; // Contents of Matrix
- };
-
-
- // Matrix Constructor. This constructor initializes the
- // matrix and allocates memory for the matrix data.
- Matrix::Matrix(int x, int y, int const *data = 0)
- {
- // Set matrix size (numbering system 0 to X-1)
- xdim = (x-1);
- ydim = (y-1);
-
- // Allocate memory for matrix
- MatrixData = new int[x*y];
-
- // Check for memory allocation error
- if (MatrixData == 0) throw "Memory Allocation Error";
-
- // Copy Data to Matrix if Available
- if (data !=0)
- for (int i=0; i<x*y; i++) MatrixData[i] = data[i];
- else
- for (int i=0; i<x*y; i++) MatrixData[i] = 0;
-
- }
-
- // This constructor is for special cases where we don't
- // know what the resulting member will look like.
- Matrix::Matrix()
- {
- xdim = 0;
- ydim = 0;
- MatrixData = 0;
- }
-
- // Matrix Destructor. Clean up the mess.
- Matrix::~Matrix()
- {
- // Free up the memory used
- delete MatrixData;
- }
-
- // This is used for copying and assignment (ie. Matrx = Matrx2;)
- Matrix::Matrix(const Matrix &Mat)
- {
- int size = (Mat.xdim+1)*(Mat.ydim+1);
- MatrixData = new int[size];
-
- xdim = Mat.xdim;
- ydim = Mat.ydim;
-
- // Copy the Data over
- for (int i=0; i<size; i++) MatrixData[i] = Mat.MatrixData[i];
-
- }
-
- // This function is used to get a specific value from a
- // matrix in position (x,y)
- int Matrix::GetData(int x,int y)
- {
- // Convert to matrix indices
- x--;
- y--;
-
- // Make sure X and Y are within bounds
- if (x<0 || x>xdim) throw("X out of Matrix Bounds");
- if (y<0 || y>ydim) throw("Y out of Matrix Bounds");
-
- // Return Value if no Exceptions Raised
- return MatrixData[y+x*(ydim+1)];
- }
-
- // Set a value in a Matrix
- void Matrix::SetData(int x,int y,int value)
- {
- // Convert to matrix indices
- x--;
- y--;
-
- // Make sure X and Y are within bounds
- if (x<0 || x>xdim) throw("X out of Matrix Bounds");
- if (y<0 || y>ydim) throw("Y out of Matrix Bounds");
-
- MatrixData[y+x*(ydim+1)] = value;
- }
-
- // Display the Contents of the Matrix
- void Matrix::Display(void)
- {
- // Just in Case...
- if (MatrixData == 0) throw("Internal Matrix Error!");
-
- cout << xdim+1 << "x" << ydim+1 << " Matrix" << endl;
-
- // Display Matrix
- for (int x=0; x<=xdim; x++)
- {
- for (int y=0; y<=ydim; y++)
- {
- // For Formatting Purposes
- if (MatrixData[y+x*(ydim+1)] < 10)
- cout << " ";
-
- cout << " " << MatrixData[y+x*(ydim+1)];
- }
- cout << endl;
- }
- }
-
-
- // * operator for Matrices
- Matrix operator * (Matrix M1, Matrix M2)
- {
- // M1 columns must equal M2 rows
- if (M1.ydim != M2.xdim)
- throw "Matrices cannnot be multiplied!";
-
- Matrix M3(M1.xdim+1,M2.ydim+1);
-
- // Do the Multiplication
- for (int i=1; i<M1.Xdim(); i++)
- for (int j=1; j<M2.Ydim(); j++)
- {
- M3.SetData(i,j,0);
- for (int k=1; k<M2.Xdim(); k++)
- M3.SetData(i,j,M3.GetData(i,j)+
- M1.GetData(i,k)*M2.GetData(k,j));
- }
-
- return M3;
- }
-
- // This is for multiplication by a Scalar
- Matrix operator * (Matrix M1, int Scalar)
- {
- Matrix Temp(M1.xdim+1,M1.ydim+1);
- int size = (M1.xdim+1)*(M1.ydim+1);
-
- // Multiply matrix by scalar
- for (int i=0; i<size; i++)
- Temp.MatrixData[i] = M1.MatrixData[i] * Scalar;
-
- return Temp;
- }
-
- // Add two Matrices together
- Matrix operator + (Matrix M1, Matrix M2)
- {
- // Matrices must be same dimensions
- if ((M1.xdim != M2.xdim)||(M1.ydim != M2.ydim))
- throw "Matrices cannot be added!";
-
- Matrix Temp(M1.xdim+1,M1.ydim+1);
- int size = (M1.xdim+1)*(M1.ydim+1);
-
- // Do the addition
- for (int i=0; i<size; i++)
- Temp.MatrixData[i] = M1.MatrixData[i] + M2.MatrixData[i];
-
- return Temp;
- }
-
- // Subtract two Matrices
- Matrix operator - (Matrix M1, Matrix M2)
- {
- // Matrices must be same dimensions
- if ((M1.xdim != M2.xdim)||(M1.ydim != M2.ydim))
- throw "Matrices cannot be subtracted!";
-
- Matrix Temp(M1.xdim+1,M1.ydim+1);
- int size = (M1.xdim+1)*(M1.ydim+1);
-
- // Do the Subtraction
- for (int i=0; i<size; i++)
- Temp.MatrixData[i] = M1.MatrixData[i] - M2.MatrixData[i];
-
- return Temp;
- }
-
- // Define matrix data as arrays
- int Mat4x4a[16] = {1, 2, 3, 4,
- 5, 6, 7, 8,
- 9, 10,11,12,
- 13,14,15,16};
-
- int Mat4x4b[16] = {0, 1, 1, 1,
- 1, 0, 1, 1,
- 1, 1, 0, 1,
- 1, 1, 1, 0};
-
- main()
- {
- // Define Two Matrix Variables
- Matrix M1(4,4, Mat4x4a);
- Matrix M2(4,4, Mat4x4b);
-
- // Test Matrix Operations
- Matrix M3 = M1 * M2;
- Matrix M4 = M2 * M1;
- Matrix M5 = M1 + M2;
-
- // Print out the Results
- cout << "Matrix A:" << endl; M1.Display();
- cout << "Matrix B:" << endl; M2.Display();
- cout << "Matrix A*B:" << endl; M3.Display();
- cout << "Matrix B*A:" << endl; M4.Display();
- cout << "Matrix A+B:" << endl; M5.Display();
-
- return 0;
- }
- --
-